import { Matrix, MatrixData } from "./Matrix.js";

const ERASE_INTERVAL = 25;

export interface IEraserOptions {
    matrix: Matrix;
    render: () => void;
    interval?: number;
}

export class Eraser {
    #fulls: number[] = [];
    readonly #options: Readonly<IEraserOptions>;

    constructor(options: IEraserOptions) {
        options.interval ??= ERASE_INTERVAL;
        this.#options = options;
    }

    private get matrix(): Matrix {
        return this.#options.matrix;
    }

    get rowsCount(): number {
        return this.#fulls?.length ?? 0;
    }

    check(): boolean {
        const fulls = this.#fulls = this.matrix.getFullRows();
        return !!fulls.length;
    }

    async erase(): Promise<MatrixData> {
        const matrix = this.matrix;
        const width = matrix.width;
        const fulls = this.#fulls;
        const render = this.#options.render;

        return new Promise((resolve: (value?: any) => void) => {
            let x: number = 0;
            const t = setInterval(() => {
                fulls.forEach((y: number) => {
                    matrix.set(x, y);
                    render();
                });

                if (++x >= width) {
                    clearInterval(t);
                    this.matrix.removeRows(this.#fulls);
                    resolve();
                }
            }, this.#options.interval);
        });
    }
}
